// 线段数写法
// 线段树就类似于一个完全二叉树，其一个结点保存的是一段区间的信息
// 由于需要保存的是结点，所以需要4 * n 的数组范围，存储与heap类似
// 由四个操作组成，modify，pushup，query，build
#include <iostream>
#include <algorithm>

using namespace std;
const int N = 100010;
struct node
{
    int l, r, sum;
}tree[4 * N];
int w[N];
int n, m;

// 将左右孩子的信息向上传递
void pushup(int u)
{
    tree[u].sum = tree[u << 1].sum + tree[u << 1 | 1].sum;
}

// 初始化线段数 (u:根节点 [l, r]: 根节点维护的区间)
void build(int u, int l, int r)
{
    //如果已经是叶结点，就直接插入数据
    if(l == r)
    {
        tree[u] = { l, r, w[l] };
    }
    else
    {
        tree[u].l = l, tree[u].r = r;
        int mid = l + r >> 1;
        // 递归建立左右子树
        build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
        // 用左右结点的信息更新当前结点的信息
        pushup(u);
    }
}

//对x的位置加上dd
void modify(int u, int x, int dd)
{
    int l = tree[u].l, r = tree[u].r;
    if(l == r) tree[u].sum += dd;
    else
    {
        // 找到x所在的位置
        int mid = l + r >> 1;
        if(x <= mid) modify(u << 1, x, dd);
        else modify(u << 1 | 1, x, dd);
        pushup(u);
    }
}

int query(int u, int l, int r)
{
    // 如果要查询的区间完全包含当前区间，直接返回
    if(l <= tree[u].l && r >= tree[u].r) 
    {
        // cout << tree[u].sum << "..." <<endl;
        return tree[u].sum;
    }
    else
    {
        int sum = 0;
        int mid = tree[u].l + tree[u].r >> 1;
        if(l <= mid) sum += query(u << 1, l, r);
        if(r > mid) sum += query(u << 1 | 1, l, r);
        return sum;
    }
}

int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n; ++i) cin >> w[i];
    build(1, 1, n);
    // cout << query(1, 1, 3) << endl;
    for(int i = 0; i < m; ++i)
    {
        int k, a, b;
        cin >> k >> a >> b;
        if(k) modify(1, a, b);
        else cout << query(1, a, b) << endl;
    }
    return 0;
}